package com.clkj.aimin.service.doctor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.clkj.aimin.dao.doctor.*;
import com.clkj.aimin.dao.notice.NoticeMapper;
import com.clkj.aimin.dao.topic.TopicCategoryMapper;
import com.clkj.aimin.dao.topic.TopicCommentsMapper;
import com.clkj.aimin.dao.topic.TopicMapper;
import com.clkj.aimin.dao.topic.TopicPriseMapper;
import com.clkj.aimin.dao.user.*;
import com.clkj.aimin.pojo.common.*;
import com.clkj.aimin.pojo.doctor.*;
import com.clkj.aimin.pojo.notice.Notice;
import com.clkj.aimin.pojo.topic.Topic;
import com.clkj.aimin.pojo.topic.TopicCategory;
import com.clkj.aimin.pojo.topic.TopicComments;
import com.clkj.aimin.pojo.topic.TopicPrise;
import com.clkj.aimin.pojo.user.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HTTP;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.util.*;

/**
 * @author yawang
 * @create 2024/04/02 16:48:51
 **/
@Repository
public class DoctorServiceImpl implements DoctorService{

    @Autowired
    private DoctorMapper doctorMapper;
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private TopicMapper topicMapper;

    @Autowired
    private TopicCategoryMapper categoryMapper;

    @Autowired
    private TopicCommentsMapper commentsMapper;

    @Autowired
    private DoctorTalkMapper talkMapper;
    @Autowired
    private DoctorTimerMapper timerMapper;

    @Autowired
    private UserRegisterMapper registerMapper;

    @Autowired
    private UserTypeMapper userTypeMapper;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private TaskMapper taskMapper;

    @Autowired
    private NoticeMapper noticeMapper;

    @Autowired
    private UserOrderMapper userOrderMapper;

    @Autowired
    private TopicPriseMapper topicPriseMapper;

    @Autowired
    private ManagerMapper managerMapper;
    @Autowired
    private UserOrderImgMapper imgMapper;

    private Map map;
    @Override
    public void addDoctor(Doctor doctor, HttpServletRequest request)
    {
        MultipartFile file = ((MultipartRequest) request).getFile("file");
        String fileName = "";
        if (file != null) {
            fileName = OSSUtil.uploadingImg(file, "doctor/doctor");
        }
        String code = Util.getRandomIntegerByLength(6);
        doctor.setRcode(code);

        doctor.setDoctorPic(fileName);
        doctorMapper.insertSelective(doctor);
    }

    @Override
    public Doctor getDoctorByOpenId(String openId) {
        Example example =  new Example(Doctor.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("openId",openId);
        return doctorMapper.selectOneByExample(example);
    }

    @Override
    public Doctor getDoctorById(Integer doctorId) {
        Example example =  new Example(Doctor.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("doctorId",doctorId);
        return doctorMapper.selectOneByExample(example);
    }

    @Override
    public void addDepartment(Department department) {
        departmentMapper.insertSelective(department);
    }

    @Override
    public List<Department> listDepartment() {
        Example example =  new Example(Department.class);
        Example.Criteria criteria = example.createCriteria();
        example.orderBy("departmentId").asc();
        return departmentMapper.selectByExample(example);
    }

    @Override
    public Map getMain(Integer userType,Integer userId) {
        map = new HashMap();
        Notice notice = noticeMapper.selectNewNotice(userType);
        map.put("notice", notice);


        Example example = new Example(Doctor.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("doctorStatus",1);
        List<Doctor> doctors = doctorMapper.selectByExample(example);
        map.put("doctors",doctors);
        if(userType==2){
            //助理医生
            //我的患者
             example = new Example(User.class);
             criteria = example.createCriteria();
            criteria.andEqualTo("helperId",userId).andEqualTo("userType",0);
            int userNum = userMapper.selectCountByExample(example);
            map.put("userNum", userNum);

            //申请列表
            example = new Example(UserOrder.class);
            criteria = example.createCriteria();
            criteria.andEqualTo("helperId",userId).andEqualTo("payType",0).andEqualTo("orderStatus",3);
            int orderNum = userOrderMapper.selectCountByExample(example);
            map.put("applyNum", orderNum);

            map.put("医助消息","userNum：患者数量，applyNum：申请数量");
        }
        if(userType==1){
            //我的患者
           example = new Example(User.class);
            criteria = example.createCriteria();
            criteria.andEqualTo("doctorId",userId).andEqualTo("userType",0);
            int userNum = userMapper.selectCountByExample(example);
            map.put("userNum", userNum);

            //我的医助
            example = new Example(User.class);
            criteria = example.createCriteria();
            criteria.andEqualTo("doctorId",userId).andEqualTo("userType",2);
           User yizhu  = userMapper.selectOneByExample(example);
            map.put("yizhu", yizhu);
            map.put("医生消息","userNum：患者数量，yizhu：医助信息");
        }
            List<Topic> topicList = topicMapper.listTopicAndVideos();
            map.put("topicList",topicList);
            map.put("msg","doctors:名医列表   topicList三条视频，三条文章;");


        return map;
    }

    @Override
    public Map getTopicCommonts(Integer topicId,Integer userId) {
        map = new HashMap();
        List<TopicComments> comments = commentsMapper.listComments(topicId);
        map.put("comments",comments);

        Example example = new Example(TopicPrise.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("topicId",topicId).andEqualTo("userId",userId);
        TopicPrise prise = topicPriseMapper.selectOneByExample(example);
        map.put("prise",prise);
        return map;
    }

    @Override
    public  List<DoctorTalk> getDoctorTalk(Integer doctorId) {
        List<DoctorTalk> talks =talkMapper.listTalksByDoctor(doctorId);
        return talks;
    }

    @Override
    public List<User> listDoctors() {
        return doctorMapper.listDoctors();
    }

    @Override
    public void addComments(TopicComments comments) {
        commentsMapper.insertSelective(comments);
    }

    @Override
    public Map listDoctorTimes(Integer doctorId, Integer weekNum,String dateTime,Integer userId) {

        Example example = new Example(DoctorTimer.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("doctorId",doctorId).andEqualTo("weekNum",weekNum);

        List<DoctorTimer> times = timerMapper.selectByExample(example);
        map = new HashMap();
        example = new Example(UserRegister.class);
        criteria = example.createCriteria();
        criteria.andEqualTo("doctorId",doctorId).andEqualTo("registerDate",dateTime);
        List<UserRegister> registerList = registerMapper.selectByExample(example);
        for (DoctorTimer time : times) {
            for (UserRegister register : registerList) {
                if(time.getTimeSlot().equals(register.getTimeSlot())){
                    if(register.getUserId()==userId){
                        time.setIsRegister(1);
                    }
                    time.setSettingNum(time.getSettingNum()-1);
                }
            }
        }
        map.put("times",times);
        map.put("msg","times是所有的号，SettingNum==0，则不显示该号段，isRegister==1表示我已经挂了该号段");
        return map;
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public void addDoctorTimes(Integer doctorId, String weekNum, Integer settingNum, String timeSlot,Integer flag) {

        if(flag==1){
            addTimes(weekNum,timeSlot,doctorId,settingNum);
        }else{
            //修改
            //删除医生所有号段信息
            Example example = new Example(DoctorTimer.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("doctorId",doctorId);
            timerMapper.deleteByExample(example);
            addTimes(weekNum,timeSlot,doctorId,settingNum);



        }
    }

    private void addTimes(String weekNum,String timeSlot,Integer doctorId,Integer settingNum){
        String []week = weekNum.split(",");
        String []time = timeSlot.split(",");
        DoctorTimer timer ;
        List<DoctorTimer> timesList = new ArrayList<>();
        for (String s : week) {
            for (String s1 : time) {
                timer = new DoctorTimer();
                timer.setDoctorId(doctorId);
                timer.setWeekNum(Integer.valueOf(s));
                timer.setSettingNum(settingNum);
                timer.setTimeSlot(s1);
                timesList.add(timer);
            }
        }
        if(timesList.size()>0){
            timerMapper.insertList(timesList);
        }
    }

    @Override
    public void addUserRegister(Integer doctorId, Integer weekNum, Integer userId, String timeSlot,String registerDate,Integer departmentId) {
        UserRegister register = new UserRegister();
        register.setDoctorId(doctorId);
        register.setDateTime(DateFormatHelper.currentTimes());
        register.setUserId(userId);
        register.setTimeSlot(timeSlot);
        register.setWeekNum(weekNum);
        register.setRegisterDate(registerDate);
        register.setDepartmentId(departmentId);
        registerMapper.insertSelective(register);
    }

    @Override
    public List<Doctor> listDoctorByDepart(Integer departmentId) {
        Example example = new Example(Doctor.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("departmentId",departmentId);
        example.orderBy("doctorId").asc();
        return doctorMapper.selectByExample(example);
    }

    @Override
    public List<UserRegister> listUserRegister(Integer userId) {
        return registerMapper.listUserRegister(userId);
    }

    @Override
    public List<Doctor> listAllDoctorTimers() {
        Example example = new Example(DoctorTimer.class);
        example.orderBy("settingId").desc();

        List<DoctorTimer> times = timerMapper.selectByExample(example);

//        example = new Example(Doctor.class);
//        example.orderBy("doctorId").desc();
        List<Doctor> doctorList = doctorMapper.selectAll();
        for (Doctor doctor : doctorList) {
            List<DoctorTimer> timeList  = new ArrayList<>();
            for (DoctorTimer time : times) {
                if(doctor.getDoctorId()==time.getDoctorId()){
                    timeList.add(time);
                }
            }
            doctor.setTimesList(timeList);
        }
        return doctorList;
    }

    @Override
    public void cancelUserRegister(Integer registerId) {
        registerMapper.deleteByPrimaryKey(registerId);
    }

    @Override
    public void addDoctorTalk(Integer doctorId, Integer userId, String talkDetail, Integer parentId,Integer userType) {
        DoctorTalk t = new DoctorTalk();
        t.setDoctorId(doctorId);
        t.setUserId(userId);
        t.setTalkDetail(talkDetail);
        t.setDateTime(DateFormatHelper.currentTimes());
        t.setParentId(parentId);
        t.setUserType(userType);
        talkMapper.insertSelective(t);

    }

    @Override
    public Map updateUserType(Integer userId, String code,Integer flag,Integer doctorId) {
        map = new HashMap();
        if(flag==2){
            //医助
            Example example = new Example(UserType.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("typeCode",code);
            UserType userType = userTypeMapper.selectOneByExample(example);

            if(userType==null){
                map.put("flag","error");
                map.put("msg","该邀请码不存在");
                return map;
            }
            if(userType.getIsUsed()==1){
                map.put("flag","error");
                map.put("msg","该邀请码已被使用");
                return map;
            }
            else{
                userType.setIsUsed(1);
                userTypeMapper.updateByPrimaryKeySelective(userType);
                User user = new User();
                user.setUserId(userId);
                user.setUserType(2);
                user.setDoctorId(doctorId);
                userMapper.updateByPrimaryKeySelective(user);

                User user1 = new User();
                user1.setUserId(doctorId);
                user1.setHelperId(userId);
                userMapper.updateByPrimaryKeySelective(user1);

                map.put("flag","success");
                map.put("userType",2);
                map.put("msg","恭喜您获得医助身份");
                return map;
            }

        }else{
            Example example = new Example(Doctor.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("rcode",code);
            Doctor doctor = doctorMapper.selectOneByExample(example);
            if(doctor==null){
                map.put("flag","error");
                map.put("msg","该邀请码不存在");
                return map;
            }
            if(doctor.getInuserId()!=null){
                map.put("flag","error");
                map.put("msg","该邀请码已被"+doctor.getDoctorName()+"占用");
                return map;
            }else{
                User user = new User();
                user.setUserId(userId);
                user.setUserType(1);
                userMapper.updateByPrimaryKeySelective(user);

                doctor.setInuserId(userId);
                doctorMapper.updateByPrimaryKeySelective(doctor);
                map.put("flag","success");
                map.put("userType",1);
                map.put("msg","恭喜您获得医生身份");
                return map;
            }
        }
    }

    @Override
    public Map updateDoctor(Doctor doctor, HttpServletRequest request) {
        MultipartFile file = ((MultipartRequest) request).getFile("file");
        String fileName = "";
        if (file != null) {
            fileName = OSSUtil.uploadingImg(file, "doctor/doctor");
        }
        doctor.setDoctorPic(fileName);
        doctorMapper.updateByPrimaryKeySelective(doctor);
        map = new HashMap<String, Object>();
        map.put("doctor",doctor);

        return map;
    }

    @Override
    public List<User> listUsersByDoctor(Integer userId,Integer userType,String userName) {
        Example example =  new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        if(userType==1){//医生
            criteria.andEqualTo("doctorId",userId).andEqualTo("userType",0);
        }else{//医生助理
            criteria.andEqualTo("helperId",userId).andEqualTo("userType",0);
        }
        if(userName!=null){
            criteria.andCondition(" user_name like '%"+userName+"%'");
        }
        return userMapper.selectByExample(example);
    }

    @Override
    public List<UserRegister> listUserRegisterByDoctor(Integer doctorId) {
        return registerMapper.listUserRegisterByDoctor(doctorId);
    }

    @Override
    public Map listDoctorMain(Integer doctorId) {
        //患者总数
        Example example =  new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("doctorId",doctorId);
        int patientNum = userMapper.selectByExample(example).size();
        //问诊患者
        int talkNum = talkMapper.listTalks(doctorId).size();

        //今日预约数
        int registerNum = registerMapper.listRegister(doctorId).size();

        //我的视频以及我的文章
        List<Topic> topics = topicMapper.listTopic(doctorId);
        List<TopicCategory> categories = categoryMapper.selectAll();
        for (Topic topic : topics) {
            String []topicCategoryId = topic.getTopicCategoryId().split(",");
            String names = "";
            for (String s : topicCategoryId) {
                for (TopicCategory category : categories) {
                    if(Integer.parseInt(s)==category.getTopicCategoryId()){
                        names +=category.getCategoryName()+",";
                    }
                }
            }
            topic.setCategoryName(names);
        }
        map = new HashMap<String, Object>();
        map.put("patientNum",patientNum);
        map.put("talkNum",talkNum);
        map.put("registerNum",registerNum);
        map.put("topics",topics);
        map.put("tips", "患者总数：patientNum；问诊患者：talkNum；今日预约数：registerNum，我的三条视频以及我的文章：topics");

        return map;
    }

    @Override
    public List<Topic> listMoreTopic(Integer doctorId, Integer topicType) {
        List<Topic> topicList = topicMapper.listTopicByDoctorId(doctorId,topicType);
        return topicList;
    }

    @Override
    public String listErweima(Integer doctorId) {
        Example example = new Example(Doctor.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("doctorId",doctorId);
        Doctor doctor =  doctorMapper.selectOneByExample(example);
        String erweima =doctor.getErweima();
        if(erweima==null){
            String urls = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx8acb5a39c3a78c53&secret=1d0a0e73c2f1b7a8941174d33537e8fc";
            JSONObject demoJson = Util.getResult(urls);
            String accessToken = demoJson.get("access_token").toString();
            //调用上面方法，获取accessToken，建议对accessToken进行缓存，
            //appid：小程序appid，appsecret：小程序密钥
            Map<String, Object> params = new HashMap<>();
            //参数,一个可以直接放入参数例如:1 多个例如：id=1&name=2&...
            params.put("scene", doctorId);
            params.put("page", "pages/index/index"); //扫码后进入小程序的页面位置
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            // 接口
            HttpPost httpPost = new HttpPost("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken);
            httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
            String body = JSON.toJSONString(params);//必须是json模式的 post
            StringEntity entity = null;
            try {
                entity = new StringEntity(body);
                entity.setContentType("image/png");//也可以是image/jpg
                httpPost.setEntity(entity);
                HttpResponse response;
                response = httpClient.execute(httpPost);
                InputStream inputStream = response.getEntity().getContent();
                String picName = doctorId + ".png";//文件名加后缀，跟上面对应
                String path = "D:\\nginx-1.19.1\\html\\zhibanzhang\\resource\\aimin\\";//图片保存路径
                Util.saveToImgByInputStream(inputStream, path, picName);  //保存图片

                String endpoint = ImgApi.endpoint;
                String bucketName = ImgApi.bucketName;
                 erweima = "https://" + bucketName + "." + endpoint + "/erweima/" + picName;
                doctor.setErweima(erweima);
                doctorMapper.updateByPrimaryKey(doctor);


            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return erweima;

    }

    @Override
    public List<Task> taskList() {
        return taskMapper.selectAll();
    }

    @Override
    public void updateTask(Task task) {
        taskMapper.updateByPrimaryKeySelective(task);
    }

    @Override
    public void bandingHelper(Integer doctorId, Integer helperId) {
        Doctor doctor = new Doctor();
        doctor.setHelperId(helperId);
        doctor.setDoctorId(doctorId);
        doctorMapper.updateByPrimaryKeySelective(doctor);
    }

    @Override
    public List<User> listHelper() {
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userType",2);
        return userMapper.selectByExample(example);
    }

    @Override
    public void addArticleOrVideo(Topic topic, HttpServletRequest request) {
        if (topic.getTopicType() == 0){
            List<MultipartFile> file1 = ((MultipartRequest) request).getFiles("article");
            MultipartFile file2 = ((MultipartRequest) request).getFile("headImage");
            String articleName = "";
            if (file1.size() > 0){
               for (MultipartFile multipartFile : file1) {
                   articleName = OSSUtil.uploadingImg(multipartFile, "doctor/article") + ",";
               }
               topic.setTopicContent(articleName);
            }
            if (file2 != null){
                topic.setTopicPic(OSSUtil.uploadingImg(file2, "doctor/article/headImage"));
            }
            topicMapper.insertSelective(topic);
        }else {
            MultipartFile file2 = ((MultipartRequest) request).getFile("headImage");
            MultipartFile file3 = ((MultipartRequest) request).getFile("video");
            if (file3 != null){
                topic.setTopicContent(OSSUtil.uploadingImg(file3, "doctor/video"));
            }
            if (file2 != null){
                topic.setTopicPic(OSSUtil.uploadingImg(file2, "doctor/video/headImage"));
            }
            topicMapper.insertSelective(topic);
        }
    }

    @Override
    public void ArticleTop(String Ids, Integer zhiding, Integer orderNum, Integer topicStatus) {
        String[] split = Ids.split(",");
        Example example = new Example(Topic.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("topicId", Arrays.asList(split));
        Topic topic = new Topic();
        topic.setZhiding(zhiding);
        topic.setOrderNum(orderNum);
        topic.setTopicStatus(topicStatus);
        topicMapper.updateByExampleSelective(topic, example);
    }

    @Override
    public void addPrise(Integer userId, Integer topicId, Integer flag) {
        if(flag==0){
            Example example = new Example(TopicPrise.class);
            Example.Criteria criteria =  example.createCriteria();
            criteria.andEqualTo("userId",userId).andEqualTo("topicId",topicId);
            topicPriseMapper.deleteByExample(example);
        }else{
            TopicPrise prise = new TopicPrise();
            prise.setUserId(userId);
            prise.setTopicId(topicId);
            prise.setPriseTime(DateFormatHelper.currentTimes());
            topicPriseMapper.insertSelective(prise);
        }

    }

    @Override
    public PageInfo listAllDoctors(Integer page, Integer size, String userName) {
        PageHelper.startPage(page, size);
        Example example = new Example(Doctor.class);
        Example.Criteria criteria = example.createCriteria();
        if(userName.length()!=0&&userName!=null){
            criteria.andLike("doctorName", "%" + userName + "%");
        }
        example.orderBy("doctorId").desc();

        return new PageInfo<>(doctorMapper.selectByExample(example));
    }

    @Override
    public void updateDoctorStatus(String ids, Integer status) {
        Example example = new Example(Doctor.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("doctorId",Arrays.asList(ids.split(",")));
        Doctor doctor = new Doctor();
        doctor.setDoctorStatus(status);
        doctorMapper.updateByExampleSelective(doctor,example);

    }

    @Override
    public Map backLogin(String managerAccount, String managerPass) {
        Example example = new Example(Manager.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("managerAccount",managerAccount).andEqualTo("managerPass",managerPass);
        Manager manager =managerMapper.selectOneByExample(example);
        map = new HashMap();
        if(manager==null){
            map.put("flag","error");
            map.put("msg", "账号或密码错误");
            return map;
        }
        if(manager.getManagerStatus()==0){
            map.put("flag","error");
            map.put("msg", "该账号已被禁用");
            return map;
        }
        map.put("flag","success");
        map.put("msg", "登陆成功");
        return map;
    }

    @Override
    public Map senMessage(Integer userId,Integer doctorId, String message) {
        map = WebSocket.sendOneMessage(doctorId, message);
        return map;


    }

    @Override
    public List<UserOrder> listCurrApply(Integer doctorId) {
        List<UserOrder> orders = userOrderMapper.doctorListApply(doctorId);
        List<UserOrderImg> imgList= null;
        for (UserOrder order : orders) {
            if(order.getOrderType()==1){
                Example example = new Example(UserOrderImg.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("orderNumber",order.getOrderNumber());
                //亲情就诊
                imgList =imgMapper.selectByExample(example);
                order.setImgList(imgList);

            }
        }
        return orders;
    }

    @Override
    public Topic topicDetail(Integer topicId) {
        return topicMapper.selectByPrimaryKey(topicId);
    }


}
